using System;
using System.Collections;
using System.Text;

namespace Noea.TogSim.Model.Interfaces
{
    public delegate void ReverseHandler(ITrainSet train, ITrainEventArgs e);
    public delegate void TrackHandler(ITrainSet train, ITrainEventArgs e);
    public delegate void ChangeHandler(ITrainSet train, ITrainEventArgs e);

    public interface ITrainSet
    {
        //  Properties
        /// <summary>
        /// Identification of train set
        /// </summary>
        int Id { get;}
        /// <summary>
        /// Description of the train set
        /// </summary>
        string Description { get; set;}
        /// <summary>
        /// The number of cars
        /// </summary>
        int Count { get;}
        /// <summary>
        /// The total length of the train set in meters
        /// </summary>
        double Length { get;}
        /// <summary>
        /// The first car in the train set, relative to the driving direction 
        /// </summary>
        ICar FirstCar { get;}
        /// <summary>
        /// The last car in the train set, relative to the driving direction 
        /// </summary>
        ICar LastCar { get;}
        /// <summary>
        /// Collection of cars in the train set
        /// </summary>
        IList Cars { get;}
        /// <summary>
        /// Requested speed of the train set
        /// </summary>
        double RequestedSpeed { get; set;}
        /// <summary>
        /// Current speed of the train set
        /// </summary>
        double ActualSpeed { get; set;}
        /// <summary>
        /// Current acceleration of the train set
        /// </summary>
        double Acceleration { get; set;}
        /// <summary>
        /// Current deacceleration of the train set
        /// </summary>
        double Deacceleration { get; set;}
        /// <summary>
        /// Maximum speed that is allowed for the train set
        /// </summary>
        double MaxSpeed { get;}
        /// <summary>
        /// Driving direction, default=false;
        /// </summary>
        bool Reverse { get; set;}
        /// <summary>
        /// Location of the first car
        /// </summary>
        ITrack CurrentTrack { get;set;}
        /// <summary>
        /// Previous location of first car. Used when determing next track 
        /// </summary>
        ITrack PreviousTrack { get;set;}
        /// <summary>
        /// Controller for the train. Similar to the person controlling the locomotive.
        /// </summary>
        ILocoDriver LocoDriver { get; set;}
        /// <summary>
        /// The train engine. Responsible for moving the train on the _trackRows
        /// </summary>
        ITrainEngine Engine { get; set;}
        //	Methods
        /// <summary>
        /// Add a new car to the train set
        /// </summary>
        /// <param name="c">the new car</param>
        void Add(ICar c);
        /// <summary>
        /// Insert a new car at a given position
        /// </summary>
        /// <param name="index">posiion of the car</param>
        /// <param name="c">the new car</param>
        void Insert(int index, ICar c);
        /// <summary>
        /// Remove a given car from the train set
        /// </summary>
        /// <param name="c">the car to be removed</param>
        void Remove(ICar c);
        /// <summary>
        /// Remove the car at a given position
        /// </summary>
        /// <param name="index">the position of the car</param>
        void Remove(int index);
        /// <summary>
        /// Find the position of a given car
        /// </summary>
        /// <param name="c">the car to be found</param>
        /// <returns>the position</returns>
        int IndexOf(ICar c);
        /// <summary>
        /// Find the car at a given position
        /// </summary>
        /// <param name="index">the position</param>
        /// <returns>the car</returns>
        ICar Get(int index);

        event ReverseHandler OnReverse;
        event TrackHandler OnTrack;
        event ChangeHandler OnChange;
    }

    public interface ITrainEventArgs
    {
        ITrainSet Train { get; }
        Object OldValue { get; }
        Object NewValue { get; }
    }
}